//! \file socketaddress.hpp
//! \brief Purewell Library Socket Address Header
//! \author Yubin Lim (purewell@gmail.com)
//! \since 2008-01-25

#ifndef __PWHDR_SOCKETADDRESS_HPP__
#define __PWHDR_SOCKETADDRESS_HPP__

#include <list>
#include "types.hpp"

namespace purewell
{

class PWSocketAddress;

//! \brief Socket address list.
typedef std::list<PWSocketAddress> PWSocketAddressList;

//! \brief Socket address.
class PWAPI PWSocketAddress
{
public:
	//! \brief Get socket address size.
	//! \return Socket address size.
	size_t getSize(void) const;

	//! \brief Get max size of socket address.
	//! \return Max size of socket address.
	size_t getMaxSize(void) const;

	//! \brief Get socket name.
	//! \param[out] host Host name buffer.
	//! \param[in] hlen Host name buffer size.
	//! \param[out] service Service/Port name buffer.
	//! \param[in] slen Service/Port name buffer size.
	//! \param[out] err Error code.
	bool getName(char* host, size_t hlen,
		char* service, size_t slen, int* err) const;

	//! \brief Get socket name.
	//! \param[out] host Host name buffer.
	//! \param[in] hlen Host name buffer size.
	//! \param[out] service Service/Port name buffer.
	//! \param[in] slen Service/Port name buffer size.
	//! \param[in] flag Flags for get name hint.
	//! \param[out] err Error code.
	bool getName(char* host, size_t hlen,
		char* service, size_t slen, int flag, int* err) const;

	//! \brief Get BSD socket address pointer.
	//! \return BSD socket address pointer(struct sockaddr*).
	void* getAddress(void);

	//! \brief Get BSD socket address pointer.
	//! \return BSD socket address pointer(struct sockaddr*).
	const void* getAddress(void) const;

	//! \brief Clear socket address.
	void clear(void);

	//! \brief Assign BSD socket address.
	//! \param[in] sa BSD socket address(struct sockaddr*).
	//! \param[in] slen Socket address size.
	void assign(const void* sa, size_t slen);

	//! \brief Set family.
	//! \param[in] type Family.
	void setFamily(int type);

	//! \brief Get family.
	//! \return Family.
	int getFamily(void) const;

	//! \brief Set IP information. IP4/6 only.
	//! \param[in] family Family. AF_INET, AF_INET6 only.
	//! \param[in] host Host.
	//! \param[in] service Service.
	//! \return On success, returns true.
	bool setIP(int family, const char* host, const char* service);

	//! \brief Get IP information. IP4/6 only.
	//! \param[out] family Family. If don't care, set NULL.
	//! \param[out] host Host. If don't care, set NULL.
	//! \param[out] service Service. If don't care, set NULL.
	//! \return On success, returns true.
	bool getIP(int* family, char* host, char* service) const;

	//! \brief Set UNIX socket path.
	//! \param[in] path Path.
	//! \return On success, true.
	bool setPath(const char* path);

	//! \brief Get UNIX socket path.
	//! \param[in] path Path.
	//! \return On success, true.
	bool getPath(char* path) const;

	//! \brief Get UNIX socket path.
	//! \return On success, C-style string pointer or NULL.
	const char* getPath(void) const;

	//! \brief Get UNIX socket path.
	//! \return On success, C-style string pointer or NULL.
	char* getPath(void);

	//! \brief Get max size of UNIX socket path.
	//! \return Max size of UNIX socket path.
	static size_t getMaxPathSize(void);

	//! \brief Get current UNIX socket path.
	//! \return On success, size of path or (size_t)-1.
	size_t getPathSize(void) const;

public:
	//! \brief Parse name to socket address.
	//! \param[out] lst Result of parsing.
	//! \param[in] host Host name.
	//! \param[in] service Service/Port name.
	//! \param[in] family Family.
	//! \param[in] socktype Socket type.
	//! \param[in] protocol Protocol type.
	static PWSocketAddressList& parseName(PWSocketAddressList& lst,
		const char* host, const char* service,
		int family, int socktype, int protocol);

public:
	//! \brief Default constructor.
	explicit PWSocketAddress();

	//! \brief Assign constructor.
	//! \param[in] sa Sorce address pointer.
	//! \param[in] slen Address length.
	explicit PWSocketAddress(const void* sa, size_t slen);

	//! \brief Copy constructor.
	//! \param[in] addr Source address.
	explicit PWSocketAddress(const PWSocketAddress& addr);

	//! \brief Copy constructor.
	//! \param[in] addr Source address(struct sockaddr).
	explicit PWSocketAddress(const void* addr);

	//! \brief Destructor.
	virtual ~PWSocketAddress();

public:
	//! \brief Assign operator.
	//! \param[in] addr Source address.
	//! \return Instance reference.
	PWSocketAddress& operator = (const PWSocketAddress& addr);

protected:
	char	m_sa[PWSA_MAX_LEN];		//!< Socket address.
	size_t	m_slen;					//!< Socket length.
};

};//namespace purewell

#endif//!__PWHDR_SOCKETADDRESS_HPP__

